home *** CD-ROM | disk | FTP | other *** search
-
- Page 60,132
- Title TURBORUN a utility for Turbo Pascal, MS/PC-DOS v2.xx
- Name TurboRun
-
- ;************************************************************************
- ;* *
- ;* T U R B O R U N *
- ;* Version 1.2 *
- ;* *
- ;* By John Cooper John Falconer *
- ;* (913) 262-8451 (415) 521-7245 *
- ;* CIS 74775,756 CIS 72435,1617 *
- ;* *
- ;* Update to Version 1.2 by *
- ;* *
- ;* Tom Devitt *
- ;* Pseudonym Software *
- ;* (818) 796-7933 *
- ;* *
- ;************************************************************************
-
- Comment*
-
- Revision History
- Version 1.0 was successfully tested on 12/10/84.
- By John Cooper
-
- Updated to Version 1.0A on 12/22/84.
- By John Falconer
-
- 1. Changed ssmax from a constant to a code-base-relative
- value. This change allows Turborun to be used with
- different versions of Turbo Pascal. Although undocumented,
- the four versions of Turbo I tested all store their
- maximum stack segment size as a word located seven bytes
- ahead of the beginning of user code.
- 2. Added code to determine the length of the command line
- which is passed to the child process. Moved the child's
- command line starting point to PSP+081H as called for in
- the DOS manual (Ver 2.0 page E-6) and placed the length
- byte for the command line at PSP+080H. This allows the
- command line passed to the child to be used as a string
- with string[0] containing the valid length. Note that
- a carriage return is placed at the end of the passed command
- line but that it is not counted in the length. Note also
- that this change corrupts the CmdLine variable passed
- to Turborun by changing the last character of the file
- name to the length of the child's CmdLine.
- 3. Changed original code so that all characters on the command
- line are passed on to the child. This is as called for in
- the DOS manual. Previously the first terminator (usually
- a space) was skipped over.
- 4. Corrected a few minor documentation errors.
-
- Note: The EXEC call does not support IO-Redirection on the command
- line.
- *
- Page
- Comment *
-
- Updated to Version 1.0B January 10, 1985
- By John Cooper
-
- 1. A note concerning the lack of IO-redirection support
- by the MS/PC DOS EXEC function call, the call which is
- at the heart of this program, was ammended, as it has
- been determined that, at least in the case of MS-DOS 2.11,
- EXEC does provide full IO-redirection, via the command line
- symbols "> < |", if the command processor is envolked ahead
- of the child.
-
- <Child> [FCB-1 [FCB-2]] >PIPEOUT <PIPEIN
-
- The above will NOT work, however,
-
- [path][drive]COMMAND.COM /C <Child> [FCB-1 [FCB-2]] >PIPEOUT <PIPEIN
-
- should work just fine.
-
-
- 2. Changed the way in which the program detects the end
- of the childs name, to include all filename separators,
- as listed on page 1-88 of MS-DOS v2.0 Programmer's
- Reference, except the back-slash (\) and colon (:). These
- two were excluded because the program needs to accept a
- full-path name, which could include these symbols. Pre-
- viously only a space or null was considered a terminator.
- This change was recommended but not implemented in version
- 1.0A.
-
- 3. Added notes on installation concerning the requirement,
- introduced by an enhancement made in 1.0A, that the
- external declaration of this program be the first in the
- Turbo source code. Also added some warnings and documentation
- notes.
- *
- Page
- Comment *
-
- Updated to Version 1.1 March 17, 1985
- By John Falconer
-
- 1. A "bug" in the way memory allocation is calculated and
- set to protect Turbo's SSEG was fixed. The program is now
- known to function with such large applications as 1-2-3 and
- Dbase III.
-
- Updated to Version 1.2 on April 28, 1985
- By Tom Devitt
-
- 1. Made Version 1.2 compatible with the 2.0 AND 3.0 versions
- of Turbo Pascal by modifying the method in which ssmax
- is located. Under 3.0 TP stores the maximum stack segment
- size 20 bytes ahead of the beginning of user code. However,
- both versions store this value at CS:[101H] + 112H. This
- change should make the placement of the EXTERNAL RUN proc
- unimportant.
-
- 2. Acknowledgement: I owe a debt to the guys at Pathfinder
- Software Inc., publishers of TurboLink. Although TL 2.0
- contains a bug which makes it unusable on > 512k systems,
- I was able to discover the above fact by analysing their
- code.
-
- 3. With Turbo Pascal 2.0B, you must first compile in memory
- and only then switch over to the com option, limiting
- memory before the second compile. With Turbo Pascal
- 3.0B, you may skip the memory compile.
- *
- Page
- Comment*
-
- - - - W A R N I N G - - -
- Although every effort has been made, by the two authors, to
- ensure that this program will perform as specified, there are
- may be programs which will not function correctly when envoked
- from Turbo, via Turborun, but will do just fine if envoked
- from COMMAND.COM. An excellent example is WordStar(tm). In
- some, but not all, cases this can be solved by first envoking
- COMMAND.COM and then envoking the child from COMMAND.COM.
- Assume that there is a program, WORKING.COM, that will not
- work from Turborun but does work from DOS. The following
- command line might help;
-
- COMMAND.COM /c WORKING.COM
-
- This of course assume that there is not a shortage of
- memory of some other explainable problem. The switch, /c,
- is included to force COMMAND.COM to return control to the
- parent after the processing of its, COMMAND.COM's, command line.
-
-
- Installation Notes:
- The enhancement to provide for a version-independent SSMAX,
- provided by John F., has introduced the additional requirement
- that this external be the first code generating structute in
- the Turbo Pascal source code, i.e. make TurboRun the first
- procedure, following the Const, Type, and Var blocks, in the
- main program. Turborun assumes it is the first and can,
- therefore, find the SSMAX word exactly seven bytes prior to
- its own base address.
-
- Note: Under Version 1.2, the above requirement may be relaxed.
- - TD
-
- Memory Compiles.
- The use of this program in "memory mode" is not recom-
- mended. Turbo seems to dislike having its memory
- limited, which is required to run the child. It may
- work but it is, at best, risky! The prefered method
- is to do a memory-compile, if possible, then switch to
- Com and limit the Maximum Stack Size and compile again,
- this time producing a COM file. If compilation to memory
- is not possible, due to lack of memory or the use of
- Overlays, you MUST implement some sort of patch to
- work around Turbo Pascal 2.0B's known "bug" in its handling
- of externals greater that 128-bytes in length. The "bug"
- is easy to work around, by either loading the external
- at run-time(recommended) or converting it to an INLINE
- $Include file.
-
- Note: Above bug appears to have been fixed in Turbo
- Pascal 3.0B - TD
-
- *
- Page
- Comment *
-
- Limiting the Stack Segment for Turbo Pascal.
- If the Stack Size is not limited, at compile-time, then
- Turbo Pascal may want to consume all of the system's
- available RAM. Of course, that precludes the use of child
- processes because the BLOCK call will fail, due to a lack
- of resources. It is, therefore, recommended that you limit
- Maximum Stack Size to just enough memory to allow the Pascal
- program to operate, this will leave the balance of your
- system's resources available for child processes.
-
-
- Terminate But Stay Resident.
- Programs which use "Terminate but stay resident" or
- "Keep process" to terminate but keep itself in memory should
- not be run from Turborun. The reason is that will cause
- DOS to attempt to set the allocation block map to prevent
- overlaying of the child. If the system survives this, it
- still leave DOS in an unpredictable state.
-
-
- Exit codes.
- In order for the parent to correctly detect the reason the
- child terminated the child must pass that infomation back,
- so that the Get Return Code can find it. Many currently,
- available programs do not provide this and hence the code
- value passed back to RetCode may not reflect the actual
- reason the child was terminated. An example is COMMAND.COM.
-
- "BUGS".
- If you encounter difficulties using this program or you find
- "bugs" in it, please contact either author or the latest
- revisor.
-
-
- After this source code is assembled, linked, and converted to
- a COM file it should be included as an external procedure
- within the Turbo Pascal source file. The external should be
- of the form shown below.
-
- Procedure GoForIt(Var RetCode:Integer; Var Cmdline);
- External 'TurboRun.com';
-
- Cmdline can be either type-CHAR or type-STRING. If the latter
- is used you should pass CmdLine[1] to skip the length byte.
-
- Format of CmdLine:
- path-name-to-child [<sp> First-FCB [<sp> Second-FCB [<sp> switchs and/or IO redirection]]] #0
-
- Notice that the Cmdline to followed by a byte of 0, this is binary 0
- not ASCII 0. <-- VERY IMPORTANT!
-
- *
- Page
- Comment *
-
- The variable, RetCode, will contain the return code from the
- child process. RetCode is actually used as two, seperate,
- byte-length variables. The table below explains how to interpret
- this variable in terms of its high and low bytes.
-
- High byte
- 0 : Normal Termination, No error
- 1 : Child was terminated via by CONTROL-C
- 2 : Child was aborted because of a DOS Hard Error
- 3 : Child used terminate-but-stay-resident
- (System needs to be rebooted)
- 4 : EXEC call failed.
- 8 : Memory allocation error, EXEC was not attempted
-
- In the cases of 0,1,2, and 3 the low byte has the value passed
- back by the child. Any of these values indicate that the EXEC
- call was successful. Programs which use terminate-but-stay-
- resident should not be called by the program.
-
- In the case of 4 the low byte has the reason the EXEC failed.
- 2 : The path specified was invalid or not found.
- 8 : There was not enough memory for the process to be created.
- 11 : The process was an EXE format file and contained information
- that was internally inconsistent.
-
- In the case of 8 the low byte has the reason the memory allocation
- request failed.
- 7 : The arena was trashed because a user program has changed
- memory that does not belong to it. System needs to be Rebooted.
- 8 : Insufficient memory.
-
- *
- Page
- Subttl Main Program
- ;
- ;------------------- E Q U A T E S --------------------
- ;
- spsave equ cs:00fch ;Storage for SP register
- sssave equ cs:00feh ;Storage for SS register
- ;
- ;-------------------- M A C R O S ---------------------
- ;
- MsDos Macro function
- If function lt 256
- mov ah,function
- Else
- mov ax,function
- EndIf
- int 21h
- EndM
- ;
- ;
- ;------------------ M A I N P R O G R A M -----------------
- ;
- code segment para public 'CODE'
- assume cs:code,ds:nothing,es:code,ss:nothing
-
- org 00h
- run proc near
- call entry ;Find out where we were loaded
- ;There is no return from this CALL
- separate db ';,=+"[]><| ',9,0 ;Filename separators
- ;Excluding ":" and "\" which cannot appear in
- ;a filename but can appear in a pathname.
-
- child db 128 dup(?) ;Path to child (with filename extension)
- fcb1 db 16 dup(?) ;Optional fcb
- fcb2 db 16 dup(?) ;Optional fcb
- parablk dw 0,12 dup(?) ;Parameter block (DOS 2.0 Manual p. D-45)
- cmdstrt dw 0 ;Offset to first char in child's CmdLine
- ssmax dw 0 ;Storage for parent's maximum stack size,
- ;in paragraphs
-
- entry: pop bx ;Offset+3
- sub bx,3 ;Actual offset address of RUN.COM
- pop dx ;Turbo(tm) return address
- pop si ;Offset to command string
- pop cx ;Segment address of command string
- push dx ;Restore turbo's RET address
- mov dx,si
- push ds
- push bp
- pushf
-
- push bx ;Save bx temporarily
- mov ax,112h ;Offest of ssmax
- mov bx,CS:[101H] ;pointer to user code
- add bx,ax ;bx = addr ssmax
- mov ax,cs:[bx] ;Move it to ax
- pop bx ;Recover bx
- mov [ssmax+bx],ax ;Save the max stack size for SETBLOCK call
-
- mov ds,cx ;Point to command string segment
- push cs ;Make ES=CS
- pop es
- mov di,offset child ;Child process path name
- add di,bx ;Relocation offset
- cld ;Force direction
- cmdlp: lodsb ;Get character
- push di ;Save DI
- mov cx,13 ;look for any of 13 filename separators
- mov di,offset separate
- add di,bx ;Relocation offset
- repnz scasb ;Look for match
- jz endstr ;Exit if a separator is found
- pop di ;Otherwise, retrieve DI and continue
- stosb ;Store byte
- jmp cmdlp ;Try next character
- endstr: pop di ;Retrieve DI
- mov [cmdstrt+bx],si ;Pointer to first char in child's CmdLine
- mov al,0 ;Put terminating 0 in child path
- stosb
- dec si ;Back up one for stosb
- dec si ;Back up one for the length byte
-
- ;ds:si point to the childs command line
-
- u1: mov [parablk+2+bx],si ;Store offset address
- inc si ;Start parsing at head of child's CmdLine
- mov cx,ds
- mov [parablk+4+bx],cx ;Store segment address
- mov di,offset fcb1 ;Setup to parse first filename
- add di,bx ;Relocation
-
- ;di has offset from cs to default FCB passed at 5Ch
-
- mov [parablk+6+bx],di
- MsDos 2901h ;Ignore leading separators
- mov di,offset fcb2 ;Parse second filename
- add di,bx ;Relocation
-
- ;di has offset from cs to default FCB passed at 6Ch
-
- mov [parablk+10+bx],di
- MsDos 2901h
- ;
- ;Place <cr> at end of CmdLine, calculate and store child's CmdLine length
- ;
- u2: cmp byte ptr ds:[si],0 ;Look for end of line
- jz u3
- inc si
- jmp u2
- u3: mov byte ptr ds:[si],13
-
- mov ax,[cmdstrt+bx] ;Get pointer to first char in child's CmdLine
- xchg ax,si ;Swap it with current pointer
- dec si ;We don't include the <cr> in our length
- sub ax,si ;Calculate the length
- dec si ;Point to the length byte
- mov byte ptr ds:[si],al ;Store calculated length there
-
- mov cx,cs ;Setup segments in parameter block
- mov [parablk+8+bx],cx
- mov [parablk+12+bx],cx
- mov [parablk+bx],0 ;Pass environment to child, unchanged
-
- ;Now the childs parameter block is setup.
- ;All that remains is to allocate memory and go for it.
-
- push bx ;Save reloc register
- mov bx,[ssmax+bx]
- push cx
- mov cx,ss
- add bx,cx
- pop cx
- sub bx,cx
- MsDos 4ah ;Modify memory allocation
- jnc $+5
- jmp alocer ;Allocation error, Exit
- pop bx ;Recover reloc register
- push bx ;Save a copy on stack
- mov dx,bx
- add bx,offset parablk
- mov [spsave],sp ;Save SP
- mov [sssave],ss ;Save SS
- push cs ;Point ds:sx to child
- pop ds
- add dx,offset child
- MsDos 4b00h ;Go for it
- cli ;Prevent interuption
- mov sp,[spsave] ;Recover SP
- mov ss,[sssave] ;Recover SS
- sti
- jnc $+5
- jmp runerr ;Problems, Exit
- pop bx ;Get reloc register
- MsDos 4dh ;Get return code from child
- getbac: popf ;Turbo's Flags
- pop bp ;Turbo's BP
- pop ds ;Turbo's DS
- pop cx ;Return address
- pop di ;Offset to RC Variable
- pop es ;Segment of RC Variable
- mov es:[di],ax ;Store return code
- push cx ;Restore return address
- ret ;Back to Turbo
-
- alocer: pop bx ;Reloc register
- mov ah,8 ;Indicate Allocation error
- jmp getbac
- runerr: pop bx
- mov ah,4 ;Indicate RUN error
- jmp getbac
- run endp
- code ends
- end run